package com.example.demo.information.service.impl;

import com.example.demo.common.utils.Constant;
import com.example.demo.information.entity.*;
import com.example.demo.information.repository.PhotoRepository;
import com.example.demo.information.service.PhotoService;
import com.google.common.collect.Lists;
import com.google.common.io.Files;
import org.apache.commons.lang3.StringUtils;
import org.apache.tomcat.util.http.fileupload.FileUtils;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;

@Service
@Transactional(rollbackFor = Exception.class)
public class PhotoServiceImpl implements PhotoService {
    @Autowired
    private PhotoRepository photoRepository;

    @Override
    public List<Photo> findByXsxxIdAndStatusOrderByLrsjDesc(Long xsxxId, Integer status) {
        return photoRepository.findByXsxxIdAndStatusOrderByLrsjDesc(xsxxId,status);
    }
    /**
     * 保存照片信息
     * @param student
     * @param spId
     * @param bkColor
     * @param truePath
     * @param resultSavePath
     * @param internetPath
     * @return
     */
    @Override
    public String savePhotoByStudent(Student student, String spId, String bkColor
            , String truePath, String resultSavePath, String internetPath, String xgr) {
        Date date = new Date();
        String xgsj = Constant.formatter.get().format(date);
        //List<Photo> list = photoRepository.findByXsxxIdAndStatusOrderByLrsjDesc(student.getId(),1);
        Photo photo = photoRepository.findByXsxxIdAndXxxxIdAndBjxxId(student.getId()
                ,student.getSchool().getId(),student.getBjxx().getId());
        if(photo==null){
            photo = new Photo(student);
            photo.setLrr(xgr);
            photo.setLrsj(xgsj);
        }else{
            photo.setStatus(1);
            photo.setCreatemessage(Constant.formatter2.get().format(date)
                    +"@@@"+ student.getSchool().getName()
                    +"@@@"+ student.getBjxx().getName());
            photo.setXgr(xgr);
            photo.setXgsj(xgsj);
        }
        photo.setYtpath(truePath);
        photo.setApipath(internetPath);
        photo.setSavepath(resultSavePath);
        photo.setSpid(spId);
        photo.setBkcolor(bkColor);
        photoRepository.save(photo);
        return "success";
    }

    /**
     * 确认选择临时拍摄的证件照作为正式的证件照
     * @param tempPhoto
     * @return
     */
    @Override
    public String saveHistoryPhoto(Historyphoto tempPhoto) {
        Date date = new Date();
        String xgsj = Constant.formatter.get().format(date);
        Photo photo = photoRepository.findByXsxxIdAndXxxxIdAndBjxxId(tempPhoto.getXsxxId()
                ,tempPhoto.getXxxxId(),tempPhoto.getBjxxId());
        if(photo==null){
            photo = new Photo(tempPhoto);
        }else{
            photo.setStatus(1);
            photo.setCreatemessage(tempPhoto.getCreatemessage());
            photo.setXgr(tempPhoto.getLrr());
            photo.setXgsj(tempPhoto.getLrsj());
        }
        photo.setYtpath(tempPhoto.getYtpath());
        photo.setApipath(tempPhoto.getApipath());
        photo.setSavepath(tempPhoto.getSavepath());
        photo.setSpid(tempPhoto.getSpid());
        photo.setBkcolor(tempPhoto.getBkcolor());
        photoRepository.save(photo);
        return "success";
    }

    /**
     * 下载学生的一寸照片(证件照)
     * @param stuList
     */
    @Override
    public void downLoadStuPhoto(List<Student> stuList,HttpServletResponse response) {
        Map<Long, Map<Long,List<Photo>>> photoMap = new HashMap<>();//保存照片信息  Map<xxxxId,Map<bjxxId,List<Photo>>>
        Map<Long, School> schoolMap = new HashMap<>();
        Map<Long, Bjxx> bjxxMap = new HashMap<>();
        Map<Long,Student> studentMap = new HashMap<>();
        int count =0;
        for(Student s:stuList){
            if(s.getSchool()==null||s.getBjxx()==null){
                continue;
            }
            Photo photo = photoRepository.findByXsxxIdAndXxxxIdAndBjxxId(
                    s.getId(),s.getSchool().getId(),s.getBjxx().getId());
            if(photo!=null){
                count++;
                schoolMap.put(s.getSchool().getId(),s.getSchool());
                bjxxMap.put(s.getBjxx().getId(),s.getBjxx());
                studentMap.put(s.getId(),s);
                if(photoMap.containsKey(s.getSchool().getId())){
                    Map<Long, List<Photo>> tempBjxxMap = photoMap.get(s.getSchool().getId());
                    if(tempBjxxMap.containsKey(s.getBjxx().getId())){
                        List<Photo> list = tempBjxxMap.get(s.getBjxx().getId());
                        list.add(photo);
                    }else{
                        List<Photo> list = new ArrayList<>();
                        list.add(photo);
                        tempBjxxMap.put(s.getBjxx().getId(),list);
                    }
                }else{
                    Map<Long,List<Photo>> tempBjxxMap = new HashMap<>();
                    List<Photo> list = new ArrayList<>();
                    list.add(photo);
                    tempBjxxMap.put(s.getBjxx().getId(),list);
                    photoMap.put(s.getSchool().getId(),tempBjxxMap);
                }
            }
        }
        if(count>0){
            byte[] buffer = new byte[1024];
            //生成zip文件存放位置
            String dateStr = Constant.formatter2.get().format(new Date());
            String rootPath = Constant.tempTempFolder+dateStr+"/";//文件保存的temp根目录
            String zipFileName = "学生证件照"+dateStr+".zip";
            String strZipPath = rootPath+zipFileName;
            File file=new File(rootPath);
            if(!file.isDirectory() && !file.exists()){//如果文件夹不存在,新建一个
                file.mkdirs();
            }
            try {
                ZipOutputStream out = new ZipOutputStream(new FileOutputStream(strZipPath));
                List<String> fileEntitysPathArr = Lists.newArrayList();//临时文件保存地址
                // 需要同时下载的多个文件
                for(Map.Entry<Long,Map<Long,List<Photo>>> entry:photoMap.entrySet()){//学校级
                    Long xxxxId = entry.getKey();
                    School school = schoolMap.get(xxxxId);
                    Map<Long, List<Photo>> bjPhotoMap = entry.getValue();
                    for(Map.Entry<Long,List<Photo>> entry2:bjPhotoMap.entrySet()){//班级级
                        Long bjxxId = entry2.getKey();
                        Bjxx bjxx = bjxxMap.get(bjxxId);
                        String contentPathBody = school.getName()+"/"+bjxx.getName()+"/";
                        String contentPath = rootPath + contentPathBody;//班级级下的子目录
                        File sonFile=new File(contentPath);
                        if(!sonFile.isDirectory() && !sonFile.exists()){//如果文件夹不存在,新建一个
                            sonFile.mkdirs();
                        }
                        List<Photo> photoList = entry2.getValue();
                        for(Photo photo: photoList){//学生级
                            if(photo==null||StringUtils.isBlank(photo.getSavepath())){continue;}
                            String photoPath = photo.getSavepath();//证件照文件路径
                            File fileTemp = new File(photoPath);
                            if(!fileTemp.exists()){//文件读不到
                                continue;
                            }
                            FileInputStream fin = null;
                            String fileExt = photoPath.substring(photoPath.lastIndexOf("."));
                            String fileName = "";//文件导出时的命名方式?
                            //TODO 文件导出的命名方式应该由前端选择,此处先设置默认身份证
                            fileName = studentMap.get(photo.getXsxxId()).getSfz();
                            fileName = fileName+fileExt;
                            File fileEntity = new File(contentPath+fileName);
                            fileEntitysPathArr.add(contentPath+fileName);
                            Files.copy(fileTemp, fileEntity);
                            fin = new FileInputStream(fileTemp);
                            //out.putNextEntry(new ZipEntry(fileName));
                            out.putNextEntry(new ZipEntry(contentPathBody+fileName));
                            //设置压缩文件内的字符编码，不然会变成乱码
                            out.setEncoding("GBK");
                            int len;
                            // 读入需要下载的文件的内容，打包到zip文件
                            while ((len = fin.read(buffer)) > 0) {
                                out.write(buffer, 0, len);
                            }
                            out.closeEntry();
                            fin.close();
                        }
                    }
                }
                out.close();
                File zipFile = new File(strZipPath);
                // 写出文件到前台
                InputStream ins = new FileInputStream(zipFile);
                //  放到缓冲流里面
                BufferedInputStream bins = new BufferedInputStream(ins);
                //  获取文件输出IO流
                OutputStream outs = response.getOutputStream();
                BufferedOutputStream bouts = new BufferedOutputStream(outs);
                // 设置response内容的类型
                response.setContentType("application/x-download");
                response.setHeader("Content-disposition",
                        "attachment;filename=" + URLEncoder.encode(
                                zipFileName.substring(0,zipFileName.lastIndexOf("."))+".zip", "UTF-8"));
                int bytesRead = 0;
                byte[] buffer1 = new byte[2048];
                // 开始向网络传输文件流
                while ((bytesRead = bins.read(buffer1, 0, 2048)) > 0) {
                    bouts.write(buffer1, 0, bytesRead);
                }
                bouts.flush();
                ins.close();
                bins.close();
                outs.close();
                bouts.close();
                for(String str:fileEntitysPathArr){//删除临时保存的文件
                    File temp=new File(str);
                    if(temp.exists()){
                        temp.delete();
                    }
                }
                File temp=new File(strZipPath);//删除临时保存的压缩包
                if(temp.exists()){
                    temp.delete();
                }
                File temp2=new File(rootPath);//删除临时保存的文件夹地址
                if(temp2.exists()){
                    FileUtils.deleteDirectory(temp2);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public Photo findByXsxxIdAndXxxxIdAndBjxxId(Long xsxxId, Long xxxxId, Long bjxxId) {
        return photoRepository.findByXsxxIdAndXxxxIdAndBjxxId(xsxxId,xxxxId,bjxxId);
    }

    @Override
    public Photo findById(Long id) {
        return photoRepository.findById(id).get();
    }


}
